<?php
namespace Hangpu888\Hpadmin\model;

use Hangpu888\Hpadmin\Model;
use Hangpu888\Hpadmin\utils\manager\HttpManager;
use Exception;
use support\Redis;
use think\facade\Cache;

class AdminLog extends Model
{
    // 自动时间戳
    protected $autoWriteTimestamp = 'datetime';
    // 定义时间戳字段名
    protected $createTime = 'ctime';
    protected $updateTime = null;
    
    // 设置JSON字段转换
    protected $json = ['params'];
    // 设置JSON数据返回数组
    protected $jsonAssoc = true;

    // 一对一（查询对应角色）
    public function role()
    {
        return $this->hasOne(AdminRole::class, 'id', 'role_id');
    }

    // 一对一（查询对应管理员）
    public function admin()
    {
        return $this->hasOne(Admin::class, 'id', 'admin_id');
    }
    
    /**
     * 查询数据
     *
     * @param array $where
     * @return object
     */
    public function findData(array $where) : object
    {
        $data = $this->with(['role','admin'])->where($where)->find();
        if ($data) {
            $data->role_title = $data->role->title;
            $data->admin_title = $data->admin->nickname;
            $data->admin_name = $data->admin->username;
            $type = ['登录','增加','修改','删除'];
            $data->type_text = $type[$data->type];
            $data->params_text = $data->params;
        }
        return $data;
    }

    /**
     * 日志记录
     *
     * @param string $path 路由地址
     * @param string $ip ip地址
     * @param integer $admin_id 管理员ID
     * @param integer $role_id 角色ID
     * @param integer $action_type 操作类型
     * @param array $data 操作数据
     * @return boolean
     */
    public function addLog(string $path, string $ip, int $admin_id, int $role_id, int $action_type, array $data) : bool
    {
        try {
            $cityData                   = $this->getCityName($ip);
        } catch (\Exception $e) {
            $message                    = $e->getMessage();
            $cityData                   = [
                'city'                  => $message,
                'isp'                   => '无'
            ];
        }
        try {
            list($module, $controller, $action) = explode('/', $path);
            $action_path                = "{$controller}/{$action}";
            // 获取操作名
            $action_name                = $this->getActionName($action_path);
            
            // 存入数据对象
            $this->admin_id             = $admin_id;
            $this->role_id              = $role_id;
            $this->action_name          = $action_name;
            $this->action_ip            = $ip;
            $this->city_name            = $cityData['city'];
            $this->isp_name             = $cityData['isp'];
            $this->action_type          = $action_type;
            $this->path                 = $path;
            $this->params               = $data;

            // 记录日志
            return $this->save();
        } catch (\Exception $e) {
            throw new Exception($e->getMessage());
        }
    }


    /**
     * 写入开发日志
     *
     * @param string $text
     * @param array $data
     * @return void
     */
    public static function dev_log(string $text, array $data)
    {
        // $web_root_path = str_replace('\\', '/', root_path());
        return false;
        $web_root_path = str_replace('\\', '/', '');
        $date = date('Y-m-d H:i:s');
        $resutil = var_export($data, true);
        $message = "时间:{$date}，原因:{$text}:{$resutil}\n";
        if (file_put_contents($web_root_path . "/runtime/dev.log", $message, FILE_APPEND)) {
            echo $message;
            exit;
        } else {
            throw new Exception(json_encode($data, 256));
        }
    }

    /**
     * 根据IP地址获取城市名称
     *
     * @param string $ip
     * @return string
     */
    private function getCityName(string $ip): array
    {
        try {
            $redisCache = Cache::get($ip);
            if ($redisCache) {
                return $redisCache;
            }
            $token = config('plugin.hangpu888.hpadmin.secretkey.ip138.key');
            // 开启日志
            if (!$token) {
                throw new Exception('未配置参数');
            }
            // 判断内网IP
            if (!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
                throw new Exception('内网IP');
            }
            $url = "https://api.ip138.com/ip/?ip={$ip}&datatype=jsonp&token={$token}";
            $response = HttpManager::get($url);
            if ($response['ret'] != 'ok') {
                throw new Exception('获取地址失败');
            }
            if (!isset($response['data'][2]) || empty($response['data'][2])) {
                throw new Exception('获取城市失败');
            }
            $data['city']           = "{$response['data'][0]}-{$response['data'][1]}-{$response['data'][2]}";
            $data['isp']            = isset($response['data'][4]) ? $response['data'][4] : '无运营商';

            // 缓存数据（1小时过期）
            Cache::set($ip, $data, 3600);

            // 返回数据
            return $data;
        } catch (\Throwable $e) {
            throw new Exception($e->getMessage());
        }
    }

    /**
     * 获取本次操作菜单名称
     *
     * @param string $path 控制器+方法请求地址
     * @return string
     */
    private function getActionName(string $path): string
    {
        $info = AuthRule::where(['path' => $path])->find();
        if (!$info) {
            return '无';
        }
        return $info->title;
    }
}
